{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=\"red\">注</font>: 使用 tensorboard 可视化需要安装 tensorflow (TensorBoard依赖于tensorflow库，可以任意安装tensorflow的gpu/cpu版本)\n",
    "\n",
    "```shell\n",
    "pip install tensorflow\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-25T06:54:07.251409900Z",
     "start_time": "2024-07-25T06:53:57.265381800Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-03T12:37:29.306526Z",
     "iopub.status.busy": "2025-02-03T12:37:29.306042Z",
     "iopub.status.idle": "2025-02-03T12:37:32.498358Z",
     "shell.execute_reply": "2025-02-03T12:37:32.497574Z",
     "shell.execute_reply.started": "2025-02-03T12:37:29.306489Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=10, micro=14, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.0\n",
      "torch 2.5.1+cu124\n",
      "cuda:0\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n",
    "seed = 42\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "## 数据准备\n",
    "\n",
    "https://www.kaggle.com/competitions/cifar-10/data\n",
    "\n",
    "```shell\n",
    "$ tree -L 1 cifar-10                                    \n",
    "cifar-10\n",
    "├── sampleSubmission.csv\n",
    "├── test\n",
    "├── train\n",
    "└── trainLabels.csv\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-25T06:54:07.496010900Z",
     "start_time": "2024-07-25T06:54:07.256405800Z"
    },
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2025-02-03T12:39:48.258343Z",
     "iopub.status.busy": "2025-02-03T12:39:48.257836Z",
     "iopub.status.idle": "2025-02-03T12:39:51.177198Z",
     "shell.execute_reply": "2025-02-03T12:39:51.176210Z",
     "shell.execute_reply.started": "2025-02-03T12:39:48.258307Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(PosixPath('competitions/cifar-10/train/1.png'), 'frog'),\n",
      " (PosixPath('competitions/cifar-10/train/2.png'), 'truck'),\n",
      " (PosixPath('competitions/cifar-10/train/3.png'), 'truck'),\n",
      " (PosixPath('competitions/cifar-10/train/4.png'), 'deer'),\n",
      " (PosixPath('competitions/cifar-10/train/5.png'), 'automobile')]\n",
      "[(PosixPath('competitions/cifar-10/test/1.png'), 'cat'),\n",
      " (PosixPath('competitions/cifar-10/test/2.png'), 'cat'),\n",
      " (PosixPath('competitions/cifar-10/test/3.png'), 'cat'),\n",
      " (PosixPath('competitions/cifar-10/test/4.png'), 'cat'),\n",
      " (PosixPath('competitions/cifar-10/test/5.png'), 'cat')]\n",
      "50000 300000\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "DATA_DIR = Path(\".\")\n",
    "DATA_DIR1 =Path(\"competitions/cifar-10/\")\n",
    "train_lables_file = DATA_DIR / \"trainLabels.csv\"\n",
    "test_csv_file = DATA_DIR / \"sampleSubmission.csv\" #测试集模板csv文件\n",
    "train_folder = DATA_DIR1 / \"train\"\n",
    "test_folder = DATA_DIR1 / \"test\"\n",
    "\n",
    "\n",
    "#所有的类别\n",
    "class_names = [\n",
    "    'airplane',\n",
    "    'automobile',\n",
    "    'bird',\n",
    "    'cat',\n",
    "    'deer',\n",
    "    'dog',\n",
    "    'frog',\n",
    "    'horse',\n",
    "    'ship',\n",
    "    'truck',\n",
    "]\n",
    "\n",
    "def parse_csv_file(filepath, folder):\n",
    "    \"\"\"Parses csv files into (filename(path), label) format\"\"\"\n",
    "    results = []\n",
    "    #读取所有行\n",
    "    with open(filepath, 'r') as f:\n",
    "#         lines = f.readlines()  为什么加[1:]，可以试这个\n",
    "        #第一行不需要，因为第一行是标签\n",
    "        lines = f.readlines()[1:] \n",
    "    for line in lines:#依次去取每一行\n",
    "        image_id, label_str = line.strip('\\n').split(',')\n",
    "        image_full_path = folder / f\"{image_id}.png\"\n",
    "        results.append((image_full_path, label_str)) #得到对应图片的路径和分类\n",
    "    return results\n",
    "\n",
    "#解析对应的文件夹\n",
    "train_labels_info = parse_csv_file(train_lables_file, train_folder)\n",
    "test_csv_info = parse_csv_file(test_csv_file, test_folder)\n",
    "#打印\n",
    "import pprint\n",
    "pprint.pprint(train_labels_info[0:5])\n",
    "pprint.pprint(test_csv_info[0:5])\n",
    "print(len(train_labels_info), len(test_csv_info))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:39:58.533876Z",
     "iopub.status.busy": "2025-02-03T12:39:58.533395Z",
     "iopub.status.idle": "2025-02-03T12:39:58.632925Z",
     "shell.execute_reply": "2025-02-03T12:39:58.632074Z",
     "shell.execute_reply.started": "2025-02-03T12:39:58.533842Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                            filepath       class\n",
      "0  competitions/cifar-10/train/1.png        frog\n",
      "1  competitions/cifar-10/train/2.png       truck\n",
      "2  competitions/cifar-10/train/3.png       truck\n",
      "3  competitions/cifar-10/train/4.png        deer\n",
      "4  competitions/cifar-10/train/5.png  automobile\n",
      "                                filepath       class\n",
      "0  competitions/cifar-10/train/45001.png       horse\n",
      "1  competitions/cifar-10/train/45002.png  automobile\n",
      "2  competitions/cifar-10/train/45003.png        deer\n",
      "3  competitions/cifar-10/train/45004.png  automobile\n",
      "4  competitions/cifar-10/train/45005.png    airplane\n",
      "                           filepath class\n",
      "0  competitions/cifar-10/test/1.png   cat\n",
      "1  competitions/cifar-10/test/2.png   cat\n",
      "2  competitions/cifar-10/test/3.png   cat\n",
      "3  competitions/cifar-10/test/4.png   cat\n",
      "4  competitions/cifar-10/test/5.png   cat\n"
     ]
    }
   ],
   "source": [
    "# train_df = pd.DataFrame(train_labels_info)\n",
    "train_df = pd.DataFrame(train_labels_info[0:45000])\n",
    "valid_df = pd.DataFrame(train_labels_info[45000:])\n",
    "test_df = pd.DataFrame(test_csv_info)\n",
    "\n",
    "train_df.columns = ['filepath', 'class']\n",
    "valid_df.columns = ['filepath', 'class']\n",
    "test_df.columns = ['filepath', 'class']\n",
    "\n",
    "print(train_df.head())\n",
    "print(valid_df.head())\n",
    "print(test_df.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:40:00.256429Z",
     "iopub.status.busy": "2025-02-03T12:40:00.255878Z",
     "iopub.status.idle": "2025-02-03T12:40:01.385878Z",
     "shell.execute_reply": "2025-02-03T12:40:01.385056Z",
     "shell.execute_reply.started": "2025-02-03T12:40:00.256387Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "from torchvision import transforms\n",
    "\n",
    "class Cifar10Dataset(Dataset):\n",
    "    df_map = {\n",
    "        \"train\": train_df,\n",
    "        \"eval\": valid_df,\n",
    "        \"test\": test_df\n",
    "    }\n",
    "    label_to_idx = {label: idx for idx, label in enumerate(class_names)} #将类别转换为数字\n",
    "    idx_to_label = {idx: label for idx, label in enumerate(class_names)}#将数字转换为类别\n",
    "    def __init__(self, mode, transform=None):\n",
    "        self.df = self.df_map.get(mode, None)\n",
    "        if self.df is None:\n",
    "            raise ValueError(\"mode should be one of train, val, test, but got {}\".format(mode))\n",
    "\n",
    "        self.transform = transform #对图片进行变换，transform是一个函数\n",
    "        \n",
    "    def __getitem__(self, index):\n",
    "        img_path, label = self.df.iloc[index]#得到对应的图片路径和类别\n",
    "        img = Image.open(img_path).convert('RGB')#打开图片\n",
    "        # # img 转换为 channel first\n",
    "        # img = img.transpose((2, 0, 1))\n",
    "        # transform\n",
    "        img = self.transform(img) #对图片进行变换\n",
    "        # label 转换为 idx\n",
    "        label = self.label_to_idx[label]\n",
    "        return img, label #返回图片和类别\n",
    "    \n",
    "    def __len__(self):\n",
    "        return self.df.shape[0]\n",
    "    \n",
    "IMAGE_SIZE = 32\n",
    "mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]\n",
    "\n",
    "transforms_train = transforms.Compose([\n",
    "        # resize\n",
    "        transforms.Resize((IMAGE_SIZE, IMAGE_SIZE)),\n",
    "        # random rotation 40\n",
    "        transforms.RandomRotation(40),\n",
    "        # horizaontal flip\n",
    "        transforms.RandomHorizontalFlip(),\n",
    "        transforms.ToTensor(),\n",
    "        transforms.Normalize(mean, std)\n",
    "    ])\n",
    "\n",
    "transforms_eval = transforms.Compose([\n",
    "        # resize\n",
    "        transforms.Resize((IMAGE_SIZE, IMAGE_SIZE)),\n",
    "        transforms.ToTensor(),\n",
    "        transforms.Normalize(mean, std)\n",
    "    ])\n",
    "\n",
    "train_ds = Cifar10Dataset(\"train\", transforms_train)\n",
    "eval_ds = Cifar10Dataset(\"eval\", transforms_eval) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:40:02.620395Z",
     "iopub.status.busy": "2025-02-03T12:40:02.619700Z",
     "iopub.status.idle": "2025-02-03T12:40:02.624997Z",
     "shell.execute_reply": "2025-02-03T12:40:02.624272Z",
     "shell.execute_reply.started": "2025-02-03T12:40:02.620354Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "batch_size = 64\n",
    "train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True, num_workers=4)   \n",
    "eval_dl = DataLoader(eval_ds, batch_size=batch_size, shuffle=False, num_workers=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 遍历train_ds得到每张图片，计算每个通道的均值和方差\n",
    "# def cal_mean_std(ds):\n",
    "#     mean = 0.\n",
    "#     std = 0.\n",
    "#     for img, _ in ds:\n",
    "#         mean += img.mean(dim=(1, 2))\n",
    "#         std += img.std(dim=(1, 2))\n",
    "#     mean /= len(ds)\n",
    "#     std /= len(ds)\n",
    "#     return mean, std\n",
    "#\n",
    "# # 经过 normalize 后 均值为0，方差为1\n",
    "# print(cal_mean_std(train_ds))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-25T07:01:50.235242700Z",
     "start_time": "2024-07-25T07:01:50.218212400Z"
    },
    "ExecutionIndicator": {
     "show": false
    },
    "execution": {
     "iopub.execute_input": "2025-02-03T12:40:15.963981Z",
     "iopub.status.busy": "2025-02-03T12:40:15.963201Z",
     "iopub.status.idle": "2025-02-03T12:40:15.981054Z",
     "shell.execute_reply": "2025-02-03T12:40:15.980193Z",
     "shell.execute_reply.started": "2025-02-03T12:40:15.963946Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             model.0.weight             paramerters num: 864\n",
      "              model.0.bias              paramerters num: 32\n",
      "             model.2.weight             paramerters num: 9216\n",
      "              model.2.bias              paramerters num: 32\n",
      "             model.5.weight             paramerters num: 9216\n",
      "              model.5.bias              paramerters num: 32\n",
      "             model.7.weight             paramerters num: 9216\n",
      "              model.7.bias              paramerters num: 32\n",
      "            model.10.weight             paramerters num: 9216\n",
      "             model.10.bias              paramerters num: 32\n",
      "            model.12.weight             paramerters num: 9216\n",
      "             model.12.bias              paramerters num: 32\n",
      "               cls.weight               paramerters num: 5120\n",
      "                cls.bias                paramerters num: 10\n"
     ]
    }
   ],
   "source": [
    "class VGG(nn.Module):\n",
    "    def __init__(self, num_classes):\n",
    "        super().__init__()\n",
    "        self.model = nn.Sequential(\n",
    "            nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.MaxPool2d(kernel_size=2),\n",
    "            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.MaxPool2d(kernel_size=2),\n",
    "            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=\"same\"),\n",
    "            nn.ReLU(),\n",
    "            nn.MaxPool2d(kernel_size=2),\n",
    "            nn.Flatten(),\n",
    "        )\n",
    "\n",
    "        self.cls = nn.Linear(512, num_classes)\n",
    "\n",
    "        self.init_weights()\n",
    "\n",
    "\n",
    "    def init_weights(self):\n",
    "        \"\"\"使用 xavier 均匀分布来初始化全连接层、卷积层的权重 W\"\"\"\n",
    "        for m in self.modules():\n",
    "            if isinstance(m, (nn.Linear, nn.Conv2d)):\n",
    "                nn.init.xavier_uniform_(m.weight)\n",
    "                nn.init.zeros_(m.bias)\n",
    "\n",
    "    @classmethod  # 类方法\n",
    "    def from_pretrained(cls, ckpt_path, num_classes=10):  # 加载预训练接口\n",
    "        state_dict = torch.load(ckpt_path, map_location=\"cpu\")  # 加载模型\n",
    "\n",
    "        # 希望模型最后两层的参数是还是随机的\n",
    "\n",
    "        state_dict.pop(\"cls.weight\")  # 去掉最后一层的权重，cls就是vgg自己\n",
    "        state_dict.pop(\"cls.bias\")  # 去掉最后一层的偏置\n",
    "\n",
    "        model = cls(num_classes=num_classes)  # 重新实例化模型\n",
    "        # 将修改后的状态字典加载到新创建的模型实例中。\n",
    "        # 参数strict=False表示在加载状态字典时，如果字典中存在模型不期望的键或缺少某些期望的键，将不会抛出错误。\n",
    "        # 这在迁移学习中很有用，因为你可能希望覆盖或忽略一些权重。\n",
    "        model.load_state_dict(state_dict, strict=False)  # 加载模型参数\n",
    "\n",
    "        return model\n",
    "\n",
    "    def forward(self, x):\n",
    "        features = self.model(x)\n",
    "        return self.cls(features)\n",
    "\n",
    "\n",
    "for key, value in VGG(len(class_names)).named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-25T07:09:22.216355600Z",
     "start_time": "2024-07-25T07:09:22.205361600Z"
    },
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2025-02-03T12:40:18.748700Z",
     "iopub.status.busy": "2025-02-03T12:40:18.748201Z",
     "iopub.status.idle": "2025-02-03T12:40:18.758965Z",
     "shell.execute_reply": "2025-02-03T12:40:18.758079Z",
     "shell.execute_reply.started": "2025-02-03T12:40:18.748665Z"
    },
    "jupyter": {
     "outputs_hidden": false
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'generator'>\n",
      "             model.0.weight             paramerters num: 864\n",
      "              model.0.bias              paramerters num: 32\n",
      "             model.2.weight             paramerters num: 9216\n",
      "              model.2.bias              paramerters num: 32\n",
      "             model.5.weight             paramerters num: 9216\n",
      "              model.5.bias              paramerters num: 32\n",
      "             model.7.weight             paramerters num: 9216\n",
      "              model.7.bias              paramerters num: 32\n",
      "            model.10.weight             paramerters num: 9216\n",
      "             model.10.bias              paramerters num: 32\n",
      "            model.12.weight             paramerters num: 9216\n",
      "             model.12.bias              paramerters num: 32\n",
      "               cls.weight               paramerters num: 5120\n",
      "                cls.bias                paramerters num: 10\n"
     ]
    }
   ],
   "source": [
    "model=VGG(len(class_names))\n",
    "print(type(model.named_parameters()))\n",
    "for key, value in  model.named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练\n",
    "\n",
    "pytorch的训练需要自行实现，包括\n",
    "1. 定义损失函数\n",
    "2. 定义优化器\n",
    "3. 定义训练步\n",
    "4. 训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### evaluating"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:41:08.795474Z",
     "iopub.status.busy": "2025-02-03T12:41:08.794955Z",
     "iopub.status.idle": "2025-02-03T12:41:08.834890Z",
     "shell.execute_reply": "2025-02-03T12:41:08.834129Z",
     "shell.execute_reply.started": "2025-02-03T12:41:08.795437Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "        preds = logits.argmax(axis=-1)    # 验证集预测\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "        \n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### Save Best\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:41:28.344569Z",
     "iopub.status.busy": "2025-02-03T12:41:28.343847Z",
     "iopub.status.idle": "2025-02-03T12:41:28.351466Z",
     "shell.execute_reply": "2025-02-03T12:41:28.350727Z",
     "shell.execute_reply.started": "2025-02-03T12:41:28.344530Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch. \n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = -1\n",
    "        \n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "        \n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "        \n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### Early Stop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T12:41:31.773607Z",
     "iopub.status.busy": "2025-02-03T12:41:31.773079Z",
     "iopub.status.idle": "2025-02-03T12:41:31.779612Z",
     "shell.execute_reply": "2025-02-03T12:41:31.778624Z",
     "shell.execute_reply.started": "2025-02-03T12:41:31.773570Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2025-02-03T13:02:38.434907Z",
     "iopub.status.busy": "2025-02-03T13:02:38.434102Z",
     "iopub.status.idle": "2025-02-03T13:04:27.791338Z",
     "shell.execute_reply": "2025-02-03T13:04:27.790352Z",
     "shell.execute_reply.started": "2025-02-03T13:02:38.434870Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 7040/7040 [01:48<00:00, 64.61it/s, epoch=9]\n"
     ]
    }
   ],
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                preds = logits.argmax(axis=-1)\n",
    "            \n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "                    \n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(val_acc)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 10\n",
    "model = VGG(num_classes=10) #第一次先训练，得到下面best.ckpt后，再注释这一条，用下面的加载模型\n",
    "\n",
    "# 1. 定义损失函数 采用交叉熵损失\n",
    "loss_fct = nn.CrossEntropyLoss()\n",
    "# 2. 定义优化器 采用 adam\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "exp_name = \"vgg-fine-tune\"\n",
    "\n",
    "# 2. save best\n",
    "if not os.path.exists(\"checkpoints\"):\n",
    "    os.makedirs(\"checkpoints\")\n",
    "\n",
    "save_ckpt_callback = SaveCheckpointsCallback(f\"checkpoints/{exp_name}\", save_step=len(train_dl), save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=5)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_dl, \n",
    "    eval_dl, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_dl)\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### 绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T13:16:04.809681Z",
     "iopub.status.busy": "2025-02-03T13:16:04.809100Z",
     "iopub.status.idle": "2025-02-03T13:16:05.159143Z",
     "shell.execute_reply": "2025-02-03T13:16:05.158417Z",
     "shell.execute_reply.started": "2025-02-03T13:16:04.809639Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns)\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5))\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        # axs[idx].set_xticks(range(0, train_df.index[-1], 5000))\n",
    "        # axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", range(0, train_df.index[-1], 5000)))\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=100)  #横坐标是 steps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2025-02-03T13:16:21.982389Z",
     "iopub.status.busy": "2025-02-03T13:16:21.981877Z",
     "iopub.status.idle": "2025-02-03T13:16:23.021979Z",
     "shell.execute_reply": "2025-02-03T13:16:23.020963Z",
     "shell.execute_reply.started": "2025-02-03T13:16:21.982348Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.8938\n",
      "accuracy: 0.6902\n"
     ]
    }
   ],
   "source": [
    "# dataload for evaluating\n",
    "\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(f\"checkpoints/{exp_name}/best.ckpt\",weights_only=True, map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, eval_dl, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "a### fine—tunign 精调"
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T13:17:18.050667Z",
     "iopub.status.busy": "2025-02-03T13:17:18.050095Z",
     "iopub.status.idle": "2025-02-03T13:19:07.457961Z",
     "shell.execute_reply": "2025-02-03T13:19:07.456978Z",
     "shell.execute_reply.started": "2025-02-03T13:17:18.050627Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_5735/1443937527.py:36: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n",
      "  state_dict = torch.load(ckpt_path, map_location=\"cpu\") #加载模型\n",
      "100%|██████████| 7040/7040 [01:49<00:00, 64.36it/s, epoch=9]\n"
     ]
    }
   ],
   "source": [
    "model = VGG.from_pretrained(\"checkpoints/vgg-fine-tune/best.ckpt\", num_classes=10)\n",
    "# 微调（Fine-tuning）：在迁移学习或微调预训练模型时，这种方法特别有用。\n",
    "# 在这种情况下，你可能希望对模型的预训练部分（不包含\"cls\"的部分）使用较小的学习率，以避免破坏已经学到的特征。\n",
    "# 而对新添加的或需要特别训练的部分（如新的分类层，包含\"cls\"的部分）使用较高的学习率，以便更快地学习到特定任务的特征。\n",
    "optimizer = torch.optim.Adam(\n",
    "    [\n",
    "        {\n",
    "            \"params\": [value for key, value in model.named_parameters() if \"cls\" not in key],\n",
    "            \"lr\": 0.0001  # 卷积用的是预训练的参数，学习率要小一点\n",
    "        },\n",
    "    \n",
    "        {\n",
    "            \"params\": [value for key, value in model.named_parameters() if \"cls\" in key],  # 这里即全连接层\n",
    "            \"lr\": 0.0005\n",
    "        },\n",
    "     ]\n",
    "    )\n",
    "\n",
    "early_stop_callback = EarlyStopCallback(patience=5)\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_dl, \n",
    "    eval_dl, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_dl)\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-03T13:20:35.009526Z",
     "iopub.status.busy": "2025-02-03T13:20:35.008966Z",
     "iopub.status.idle": "2025-02-03T13:20:36.059807Z",
     "shell.execute_reply": "2025-02-03T13:20:36.058718Z",
     "shell.execute_reply.started": "2025-02-03T13:20:35.009485Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.7887\n",
      "accuracy: 0.7280\n"
     ]
    }
   ],
   "source": [
    "# dataload for evaluating\n",
    "\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(f\"checkpoints/{exp_name}/best.ckpt\",weights_only=True, map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, eval_dl, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 推理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "881a228ecb1a459394a8370e52c7555c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/4688 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>filepath</th>\n",
       "      <th>class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>cifar-10/test/1.png</td>\n",
       "      <td>deer</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>cifar-10/test/2.png</td>\n",
       "      <td>airplane</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>cifar-10/test/3.png</td>\n",
       "      <td>truck</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>cifar-10/test/4.png</td>\n",
       "      <td>ship</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>cifar-10/test/5.png</td>\n",
       "      <td>airplane</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              filepath     class\n",
       "0  cifar-10/test/1.png      deer\n",
       "1  cifar-10/test/2.png  airplane\n",
       "2  cifar-10/test/3.png     truck\n",
       "3  cifar-10/test/4.png      ship\n",
       "4  cifar-10/test/5.png  airplane"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# test_df\n",
    "# test_ds = Cifar10Dataset(\"test\", transform=transforms_eval)\n",
    "# test_dl = DataLoader(test_ds, batch_size=batch_size, shuffle=False, drop_last=False)\n",
    "#\n",
    "# preds_collect = []\n",
    "# model.eval()\n",
    "# for data, fake_label in tqdm(test_dl):\n",
    "#     data = data.to(device=device)\n",
    "#     logits = model(data)\n",
    "#     preds = [test_ds.idx_to_label[idx] for idx in logits.argmax(axis=-1).cpu().tolist()]\n",
    "#     preds_collect.extend(preds)\n",
    "#\n",
    "# test_df[\"class\"] = preds_collect\n",
    "# test_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导出 submission.csv\n",
    "# test_df.to_csv(\"submission.csv\", index=False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
